#pragma once

#ifdef PISTACHE_USE_SSL
#include <openssl/ssl.h>
#endif

#include <memory>

namespace Pistache
{
    namespace ssl
    {

        struct SSLCtxDeleter
        {
            void operator()(void* ptr)
            {
#ifdef PISTACHE_USE_SSL
                SSL_CTX_free(reinterpret_cast<SSL_CTX*>(ptr));

                // EVP_cleanup call is not related to cleaning SSL_CTX, just global cleanup routine.
                // TODO: Think about removing EVP_cleanup call at all
                // It was deprecated in openssl 1.1.0 version (see
                // https://www.openssl.org/news/changelog.txt):
                // "Make various cleanup routines no-ops and mark them as deprecated."
                EVP_cleanup();
#else
                (void)ptr;
#endif
            }
        };

        struct SSLBioDeleter
        {
            void operator()(void* ptr)
            {
#ifdef PISTACHE_USE_SSL
                BIO_free(reinterpret_cast<BIO*>(ptr));
#else
                (void)ptr;
#endif
            }
        };

        using SSLCtxPtr = std::unique_ptr<void, SSLCtxDeleter>;
        using SSLBioPtr = std::unique_ptr<void, SSLBioDeleter>;

#ifdef PISTACHE_USE_SSL
        inline SSL_CTX* GetSSLContext(ssl::SSLCtxPtr& ctx)
        {
            return reinterpret_cast<SSL_CTX*>(ctx.get());
        }
        inline BIO* GetSSLBio(ssl::SSLBioPtr& ctx)
        {
            return reinterpret_cast<BIO*>(ctx.get());
        }
#endif

    }
}
